﻿using LiveCharts;
using LiveCharts.Defaults;
using LiveCharts.Wpf;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;

namespace CustomWPFControl.View
{
    /// <summary>
    /// Interaction logic for LineChart.xaml
    /// </summary>
    public partial class LineChart : UserControl
    {
        public SeriesCollection Series { get; set; } = new SeriesCollection();
        private readonly Dictionary<string, Series> m_seriesMap = new Dictionary<string, Series>();

        public LineChart()
        {
            InitializeComponent();
            DataContext = this;
        }

        public void AddSeries(string seriesName, Brush stroke, List<ObservablePoint> points = null)
        {
            if (m_seriesMap.ContainsKey(seriesName))
                return;

            var values = new ChartValues<ObservablePoint>();
            if (points != null)
                values.AddRange(points);

            var fillBrush = stroke.CloneCurrentValue();
            fillBrush.Opacity = 0.3;
            
            var series = new LineSeries
            {
                Title = seriesName,
                Values = values,
                Stroke = stroke,
                Fill = fillBrush,
                LineSmoothness = 0,
            };

            Series.Add(series);
            m_seriesMap.Add(seriesName, series);
        }

        public void RemoveSeries(string seriesName)
        {
            if (m_seriesMap.TryGetValue(seriesName, out var s))
            {
                Series.Remove(s);
                m_seriesMap.Remove(seriesName);
            }
        }

        public void ClearPoints(string seriesName)
        {
            if (m_seriesMap.TryGetValue(seriesName, out var s))
            {
                s.Values.Clear();
            }
        }

        public void AddPoint(string seriesName, ObservablePoint point)
        {
            if (m_seriesMap.TryGetValue(seriesName, out var s))
            {
                var values = s.Values as ChartValues<ObservablePoint>;
                values.Add(point);
            }
        }

        public void AddPoints(string seriesName, IEnumerable<ObservablePoint> points)
        {
            if (m_seriesMap.TryGetValue(seriesName, out var s))
            {
                var values = s.Values as ChartValues<ObservablePoint>;
                values.AddRange(points);
            }
        }

        public void SetSmoothness(bool on)
        {
            foreach (var s in Series)
            {
                var series = s as LineSeries;
                series.LineSmoothness = on ? 1 : 0;
            }
        }

        public void ResetZoom()
        {
            X.MinValue = double.NaN;
            X.MaxValue = double.NaN;
            Y.MinValue = double.NaN;
            Y.MaxValue = double.NaN;

            X.MinValue = 0;
            Y.MinValue = 0;
        }

        private void ListBox_OnPreviewMouseDown(object sender, MouseButtonEventArgs e)
        {
            var item = ItemsControl.ContainerFromElement(ListBox, (DependencyObject)e.OriginalSource) as ListBoxItem;
            if (item == null) return;

            var series = (LineSeries)item.Content;
            series.Visibility = series.Visibility == Visibility.Visible
                ? Visibility.Hidden
                : Visibility.Visible;
        }
    }
}
